﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Backup.Services.Logic;
using BackupObjects;
using BackupObjects.Taging;
using Microsoft.Samples.ServiceHosting.StorageClient;
using NUnit.Framework;

namespace Backup.Services.Tests
{
    //TODO: Add a backup obj. and a tag to id. and create unit test for Load and LoadAll - where tag is check.
    [TestFixture]
    public class BackupServiceLogicTests
    {
        private static TagRepository _tagRepository;
        private static BackupRepository _backupRepository;

        const string Username = BackupRepository.UserNameAdmin;

        private Tag tag1, tag11, tag12, tag21;
        private BackupObject backupObj1, backupObj2, backupObj3;

        [SetUp]
        public void TagRepositorySetUp()
        {
            //Add tags.
            _tagRepository = new TagRepository();
            _backupRepository = new BackupRepository();

            _tagRepository
                .LoadAll()
                .ForEach(item => _tagRepository.Delete(item.Id));

            _backupRepository.LoadAll(Username);
            _backupRepository.Backups.ForEach(item => _tagRepository.Delete(item.ID));


            tag1 = new Tag() { Id = Guid.NewGuid(), Name = "Tag1Name" };
            tag11 = new Tag() { Id = Guid.NewGuid(), Name = "Tag11Name", Parent = tag1 };
            tag12 = new Tag() { Id = Guid.NewGuid(), Name = "Tag12Name", Parent = tag1 };
            tag21 = new Tag() { Id = Guid.NewGuid(), Name = "Tag2Name", Parent = tag1 };

            _tagRepository.Save(tag1);
            _tagRepository.Save(tag11);
            _tagRepository.Save(tag12);
            _tagRepository.Save(tag21);

            //Add backup obj.
            backupObj1 = new BackupObject() { ID = Guid.NewGuid(), Name = "backupObj1", Contents = new byte[] { 1, 2 }, TagIds = new List<Guid>() { tag12 } };
            backupObj2 = new BackupObject() { ID = Guid.NewGuid(), Name = "backupObj2", Contents = new byte[] { 1, 2 }, TagIds = new List<Guid>() { tag21, tag12 } };
            backupObj3 = new BackupObject() { ID = Guid.NewGuid(), Name = "backupObj3", Contents = new byte[] { 1, 2 }, TagIds = new List<Guid>() { tag21 } };

            _backupRepository.Save(backupObj1);
            _backupRepository.Save(backupObj2);
            _backupRepository.Save(backupObj3);

        }

        [Test]
        public void LoadBackupObjectLoadTest()
        {
            var backupServiceLogic = new BackupServiceLogic();
            var loadedObject= backupServiceLogic.LoadById(backupObj1.ID,Username);            

            Assert.IsNotNull(loadedObject,"The loaded backup obj is null.");
            Assert.AreEqual(backupObj1.ID,loadedObject.Id,"The id is not the same.");
            Assert.AreEqual(backupObj1.TagIds.Count,loadedObject.TagIds.Count,"Tags number is not the same.");
            Assert.AreEqual(tag12.Id,loadedObject.TagIds[0],"Tag id is not the same.");
        }

        [Test]
        public void LoadAllTest()
        {
            var backupServiceLogic = new BackupServiceLogic();
            var items = backupServiceLogic.LoadAll(Username);

            Assert.IsNotNull(items,"Items list is null");
            Assert.AreEqual(3,items.Count,"The number of items is not valid.");

            var itemsName = new List<String>() {backupObj1.Name,backupObj2.Name,backupObj3.Name};
            foreach (var backupEntity in items)
            {
                Assert.Contains(backupEntity.Name,itemsName,"The name is not valid.");
            }

            var obj2 = items.Where(item => item.Id == backupObj2.ID).First();
            Assert.IsNotNull(obj2.TagIds,"Tags cannot be null.");
            Assert.AreEqual(2,obj2.TagIds.Count,"The number of tags is not valid.");
        }

        [Test]
        public void SaveTest()
        {
            string newName = "NewName";
            var backupServiceLogic = new BackupServiceLogic();
            var item = backupServiceLogic.LoadById(backupObj1.ID,Username);

            Assert.IsNotNull(item,"The backup object is null.");
            Assert.AreEqual(backupObj1.ID,item.Id,"The id is not the same.");

            item.Name = newName;
            backupServiceLogic.Save(item);

            item = backupServiceLogic.LoadById(backupObj1.ID, Username);
            Assert.IsNotNull(item, "The backup object is null.");
            Assert.AreEqual(backupObj1.ID, item.Id, "The id is not the same.");
            Assert.AreEqual(newName, item.Name, "The name didn't changed..");

        }
    }
}
